home *** CD-ROM | disk | FTP | other *** search
/ Ian & Stuart's Australian Mac 1993 September / September 93.iso / Archives / Utilities / System / Window / Window Looks / Next WDEF 7.0 / Source / NeXT WDEF.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-17  |  14.7 KB  |  508 lines  |  [TEXT/KAHL]

  1. /*
  2.             ——————————————————————————————
  3.             My Window Definition Procedure
  4.             ——————————————————————————————
  5.             
  6.             This handles that odd window.
  7.             
  8.             ————————
  9.             89/04/20
  10.             ————————
  11.             
  12.             1.0      89/03/31    First draft based on clock window def proc (+A5 games).
  13.                   89/04/05    Fixed problem with zoom box hilite
  14.                   89/04/06    Fixed zooming
  15.                   89/04/07    Minor changes in draw, chose from two gray patterns
  16.                             to avoid odd mismatches in window dragged onscreen 
  17.                             from offscreen, added proper plainDBox & altDBoxProc 
  18.                             variations, special cased zero width titles.
  19.             1.1      89/04/09    Odd half erased scroll bar startup MPW adjusted
  20.                             [see drawGrowIcon()]
  21.             1.2      89/04/09    Fixed problem with userState updates. Working on colors!
  22.                   89/04/11    Changed size box to chevrons.
  23.                   89/04/12    Made sure inGrow only returned on hilited windows.
  24.                   89/04/20    Added Apples screenBits workaround and scroll area 
  25.                               to grow image.
  26.             2.0   89/11/10  Finished color additions and cleaned up other
  27.                             assorted bugs. JNP
  28.             
  29.             ————————————————————————————————————————————
  30.             Public Domain 1989 by Appropriate Technology
  31.             ————————————————————————————————————————————
  32.             
  33.             Please send a copy of changes/improvements to:
  34.             
  35.             Eric Celeste, Appropriate Technology, 358 North Parkview, Columbus, OH 43209, USA.
  36.             CompuServe: 76146,724. MacNET: Celeste.
  37.             
  38.             ——————————————————————————————————————————————————————————————————————
  39.             Note: This WDEF is coded in THINK C 4.0 from Think Technologies
  40.             ——————————————————————————————————————————————————————————————————————
  41.  
  42. Changes made by Josh Pritikin (11.10.89):
  43. 1. In calculateMyWindow I added a test to see if we have a color window.
  44. 2. I removed the ugly StuffHex calls and speeded the pattern packing up.
  45. 3. I added a gunk of code and special casing to totally support ColorQD!
  46. 4. The code is admitably gross in some (most) places but it works and should
  47.     serve as an example of what not to make your code look like.
  48.  
  49. GEnie:            J.Pritikin
  50. AppleLink:        D4991    (<- this will change soon)
  51. Internet:        6500stom@ucsbuxa.ucsb.edu
  52.  
  53. */
  54.  
  55. #include <Color.h>
  56. #include <MacTypes.h>
  57. #include <MemoryMgr.h>
  58. #include <MenuMgr.h>
  59. #include <OSUtil.h>
  60. #include <Quickdraw.h>
  61. #include <ToolboxUtil.h>
  62. #include <WindowMgr.h>
  63.  
  64.  
  65. /*
  66.             —————————
  67.             Constants
  68.             —————————
  69. */
  70.  
  71. /* YOU ABSOLUTELY NEED TO DEFINE THIS WHEN YOUR RUNNING THE TESTER */
  72. /* #define testing */
  73.  
  74. /* #define testing */
  75. #ifdef testing
  76. #define nil 0
  77. #endif testing
  78. #define commandKeyCode        0x00008000        /* the keymap mask for the command key */
  79. #define optionKeyCode        0x00000004        /* the keymap mask for the option key */
  80.  
  81. /*
  82.             —————
  83.             Types
  84.             —————
  85. */
  86.  
  87. typedef struct {
  88.     Rect        userState, stdState;
  89.     Boolean        buttonState;
  90. } WSDRecord, *WSDPointer, **WSDHandle;
  91.  
  92. typedef        short           SICN[16];
  93. typedef        SICN            *SICNPtr;
  94.                             
  95.  
  96. #define buttonState    (**(WSDHandle)(*(WindowPeek)window).dataHandle).buttonState
  97.  
  98. #ifdef testing
  99. pascal long nextWDEF( variation, window, message, parameter )
  100. #else
  101. pascal long main( variation, window, message, parameter )
  102. #endif
  103.     short        variation;        /* variation code on this type window */
  104.     WindowPtr    window;            /* pointer to the window */
  105.     short        message;        /* what does the window manager want us to do? */
  106.     long        parameter;        /* parameter used for many things */
  107. {
  108.     long        result;            /* the return code for the function */
  109.     long hitMyWindow(/* variation, window, parameter */);
  110.     
  111.     #ifdef testing
  112.     SetUpA5();
  113.     #else        /* this stuff lets us reference thePort, otherwise we don't need it */
  114.     /* RememberA0();
  115.     SetUpA4(); */
  116.     #endif
  117.     
  118.     result = nil;
  119.     
  120.     switch( message ) {
  121.     case( wDraw ):
  122.         drawMyWindow( variation, window, parameter );
  123.         break;
  124.     case( wHit ):
  125.         result = hitMyWindow( variation, window, parameter );
  126.         break;
  127.     case( wCalcRgns ):
  128.         calculateMyWindow( variation, window, parameter );
  129.         break;
  130.     case( wNew ):
  131.         setupWindow( variation, window, parameter );
  132.         break;
  133.     case( wDispose ):
  134.         killWindow( variation, window, parameter );
  135.         break;
  136.     case( wGrow ):
  137.         growMyWindow( variation, window, parameter );
  138.         break;
  139.     case( wDrawGIcon ):
  140.         drawGrowIcon( variation, window, parameter );
  141.         break;
  142.     }
  143.     
  144.     #ifdef testing
  145.     RestoreA5();
  146.     #else
  147.     /* RestoreA4(); */
  148.     #endif
  149.     
  150.     return( result );
  151. }
  152.  
  153. /*————————————————————
  154.             where was my window hit?
  155. ————————————————————*/
  156. long hitMyWindow( variation, window, parameter )
  157.     short        variation;        /* variation code on this type window */
  158.     WindowPtr    window;            /* pointer to the window */
  159.     long        parameter;        /* parameter used for many things */
  160. {
  161.     Point        hitLocation;
  162.     Rect        windowRect, thisRect;
  163.     long        result;
  164.     
  165.     result = wNoHit;
  166.     
  167.     SetPt( &hitLocation, LoWord( parameter ), HiWord( parameter ) );
  168.     
  169.     if ( PtInRgn( hitLocation, (*(WindowPeek)window).strucRgn ) ) {
  170.                 
  171.         windowRect = (**(*(WindowPeek)window).strucRgn).rgnBBox;
  172.         
  173.         if ( PtInRgn( hitLocation, (*(WindowPeek)window).contRgn ) ) {
  174.         
  175.             result = wInContent;                    /* in the content region */
  176.             
  177.             if ( (*(WindowPeek)window).hilited ) {
  178.                 if ( variation == documentProc || variation == (documentProc+8) ) {
  179.                     SetRect( &thisRect, 
  180.                         windowRect.right     - 16, 
  181.                         windowRect.bottom     - 16,
  182.                         windowRect.right     - 4,
  183.                         windowRect.bottom     - 4
  184.                     );
  185.                     if ( PtInRect( hitLocation, &thisRect ) ) {
  186.                         result = wInGrow;
  187.                     }
  188.                 }
  189.             }
  190.  
  191.         } else {
  192.             
  193.             result = wInDrag;                        /* in the drag area unless */
  194.             
  195.             if ( (*(WindowPeek)window).hilited ) {
  196.                 if ( (*(WindowPeek)window).goAwayFlag ) {
  197.                     SetRect( &thisRect, 
  198.                         windowRect.left     + 4, 
  199.                         windowRect.top         + 4,
  200.                         windowRect.left     + 16,
  201.                         windowRect.top         + 16
  202.                     );
  203.                     if ( PtInRect( hitLocation, &thisRect ) ) {
  204.                         result = wInGoAway;
  205.                     }
  206.                 }
  207.                 if ( (result == wInDrag) 
  208.                     && ( variation == documentProc || variation == (documentProc+8) ) 
  209.                     ) {
  210.                     SetRect( &thisRect, 
  211.                         windowRect.right     - 16, 
  212.                         windowRect.bottom     - 16,
  213.                         windowRect.right     - 4,
  214.                         windowRect.bottom     - 4
  215.                     );
  216.                     if ( PtInRect( hitLocation, &thisRect ) ) {
  217.                         result = wInGrow;
  218.                     }
  219.                 }
  220.                 if ( (result == wInDrag) 
  221.                     && (*(WindowPeek)window).spareFlag 
  222.                     ) {
  223.                     SetRect( &thisRect, 
  224.                         windowRect.right     - 16, 
  225.                         windowRect.top         + 4,
  226.                         windowRect.right     - 4,
  227.                         windowRect.top         + 16
  228.                     );
  229.                     if ( PtInRect( hitLocation, &thisRect ) ) {
  230.                         if ( (*(WindowPeek)window).dataHandle != nil ) {
  231.                             thisRect = (**(*(WindowPeek)window).contRgn).rgnBBox;
  232.                             if ( EqualRect (
  233.                                 &((**(WSDHandle)(*(WindowPeek)window).dataHandle).stdState),
  234.                                 &thisRect
  235.                             ) ) {
  236.                                 result = wInZoomIn;
  237.                             } else {
  238.                                 (**(WSDHandle)(*(WindowPeek)window).dataHandle).userState 
  239.                                 = thisRect;
  240.                                 result = wInZoomOut;
  241.                             }
  242.                         } /* datahandle */
  243.                         
  244.                     } /* in the zoom box */
  245.                     
  246.                 } /* still dragging & zoomable */
  247.                 
  248.             } /* a hilited window */
  249.         
  250.         } /* else not in content region */
  251.         
  252.     } /* in the structure region */
  253.     
  254.     return( result );
  255. } /* end of hitMyWindow() */
  256.  
  257. /*————————————————————
  258.             calculate the regions of my window
  259. ————————————————————*/
  260. calculateMyWindow( variation, window, parameter )
  261.     short        variation;        /* variation code on this type window */
  262.     WindowPtr    window;            /* pointer to the window */
  263.     long        parameter;        /* parameter used for many things */
  264. {
  265.     Rect        windowRect, portR;
  266.     
  267.     windowRect = (*window).portRect;
  268.                                             /* a fix for CWindowRecords */
  269.     if ((window->portBits.rowBytes & (3<<14)) == 0) {
  270.         OffsetRect( &windowRect, -window->portBits.bounds.left, -window->portBits.bounds.top );
  271.     } else {
  272.         portR = (**(*(CGrafPtr)window).portPixMap).bounds;
  273.         OffsetRect(&windowRect, -portR.left, -portR.top);
  274.     }
  275.     
  276.     RectRgn( (*(WindowPeek)window).contRgn, &windowRect );
  277.     
  278.     switch ( variation ) {
  279.     case ( documentProc + 8):                    /* a zooming window */
  280.     case ( documentProc + 12):                    /* a zooming window with no growing */
  281.     case ( documentProc + 13):                    /* a zooming moveable dialog */
  282.         if (!EqualRect(&((**(WSDHandle)(*(WindowPeek)window).dataHandle).stdState),&windowRect)){
  283.             (**(WSDHandle)(*(WindowPeek)window).dataHandle).userState = windowRect;
  284.         }
  285.     case ( documentProc ):                        /* a regular window */
  286.     case ( documentProc + 5 ):                    /* a moveable dialog */
  287.     case ( noGrowDocProc ):                        /* a regular window with no growing */
  288.         OpenRgn();
  289.             InsetRect( &windowRect, -4, -4 );
  290.             windowRect.top -= 16;                /* add room for the title bar */
  291.             MoveTo( windowRect.left, windowRect.top );
  292.             LineTo( windowRect.left, windowRect.bottom-2 );
  293.             LineTo( windowRect.left+2, windowRect.bottom );
  294.             LineTo( windowRect.right, windowRect.bottom );
  295.             LineTo( windowRect.right, windowRect.top+2 );
  296.             LineTo( windowRect.right-2, windowRect.top );
  297.             LineTo( windowRect.left, windowRect.top );
  298.         CloseRgn( (*(WindowPeek)window).strucRgn );
  299.         break;
  300.     case ( dBoxProc ):                            /* dialog box variation */
  301.         OpenRgn();
  302.             InsetRect( &windowRect, -8, -8 );
  303.             MoveTo( windowRect.left, windowRect.top );
  304.             LineTo( windowRect.left, windowRect.bottom-2 );
  305.             LineTo( windowRect.left+2, windowRect.bottom );
  306.             LineTo( windowRect.right, windowRect.bottom );
  307.             LineTo( windowRect.right, windowRect.top+2 );
  308.             LineTo( windowRect.right-2, windowRect.top );
  309.             LineTo( windowRect.left, windowRect.top );
  310.         CloseRgn( (*(WindowPeek)window).strucRgn );
  311.         break;
  312.     case ( plainDBox ):                            /* plain box variation */
  313.         InsetRect( &windowRect, -1, -1 );
  314.         RectRgn( (*(WindowPeek)window).strucRgn, &windowRect );
  315.         break;
  316.     case ( altDBoxProc ):                        /* shadow box variation */
  317.         OpenRgn();
  318.             InsetRect( &windowRect, -1, -1 );
  319.             MoveTo( windowRect.left, windowRect.top );
  320.             LineTo( windowRect.left, windowRect.bottom );
  321.             LineTo( windowRect.left+2, windowRect.bottom );
  322.             LineTo( windowRect.left+2, windowRect.bottom+2 );
  323.             LineTo( windowRect.right+2, windowRect.bottom+2 );
  324.             LineTo( windowRect.right+2, windowRect.top+2 );
  325.             LineTo( windowRect.right, windowRect.top+2 );
  326.             LineTo( windowRect.right, windowRect.top );
  327.             LineTo( windowRect.left, windowRect.top );
  328.         CloseRgn( (*(WindowPeek)window).strucRgn );
  329.         break;
  330.     }
  331.         
  332. } /* end of calculateMyWindow() */
  333.  
  334.  
  335. /*————————————————————
  336.             draw the growing outline, the pen is already set
  337. ————————————————————*/
  338. growMyWindow( variation, window, parameter )
  339.     short        variation;        /* variation code on this type window */
  340.     WindowPtr    window;            /* pointer to the window */
  341.     long        parameter;        /* parameter used for many things */
  342. {
  343.     Rect        growingRect;
  344.     
  345.     growingRect = *(Rect *)parameter;
  346.     
  347.     growingRect.top -= 20;                                    /* out to full size */
  348.     growingRect.left -= 4;
  349.     growingRect.bottom += 4;
  350.     growingRect.right += 4;
  351.     
  352.     FrameRect( &growingRect );                                /* the frame */
  353.     
  354.     growingRect.top += 19;
  355.     
  356.     MoveTo( growingRect.left, growingRect.top );            /* the title bar area */
  357.     LineTo( growingRect.right, growingRect.top );
  358.     
  359.     MoveTo( growingRect.right - 19, growingRect.top );         /* the scroll area */
  360.     LineTo( growingRect.right - 19, growingRect.bottom );
  361.     MoveTo( growingRect.left, growingRect.bottom - 19 );
  362.     LineTo( growingRect.right, growingRect.bottom - 19 );
  363.     
  364. } /* end of growMyWindow() */
  365.  
  366. /*————————————————————
  367. draw the size box and the scroll frame
  368. ————————————————————*/
  369. drawGrowIcon( variation, window, parameter )
  370.     short        variation;        /* variation code on this type window */
  371.     WindowPtr    window;            /* pointer to the window */
  372.     long        parameter;        /* parameter used for many things */
  373. {
  374.     Rect        thisRect;
  375.     SICN           GrowSICN;
  376.     
  377.     GrowSICN[0] = 0x5755;
  378.     GrowSICN[1] = 0xA8A8;
  379.     GrowSICN[2] = 0x5355;
  380.     GrowSICN[3] = 0xAB08;
  381.     GrowSICN[4] = 0x5375;
  382.     GrowSICN[5] = 0x8378;
  383.     GrowSICN[6] = 0xBF75;
  384.     GrowSICN[7] = 0xBF78;
  385.     
  386.     GrowSICN[8] = 0x5575;
  387.     GrowSICN[9] = 0xA078;
  388.     GrowSICN[10] = 0x6FF5;
  389.     GrowSICN[11] = 0xAFF8;
  390.     GrowSICN[12] = 0x5555;
  391.     GrowSICN[13] = 0xAAA8;
  392.     GrowSICN[14] = 0x0001;
  393.     GrowSICN[15] = 0xFFFF;
  394.  
  395.     SetPort( window );
  396.     
  397. /*————————————————————
  398. draw scroll bar frame
  399. ————————————————————*/
  400.     
  401.     thisRect = (*window).portRect;
  402.     thisRect.left = thisRect.right - 15;
  403.     MoveTo( thisRect.left, thisRect.top );
  404.     LineTo( thisRect.left, thisRect.bottom );
  405.  
  406.     thisRect.top = thisRect.bottom - 15;
  407.     thisRect.left = (*window).portRect.left;
  408.     MoveTo( thisRect.left, thisRect.top );
  409.     LineTo( thisRect.right, thisRect.top );
  410.         
  411.     /*————————————————————
  412.     draw the sizing box 
  413.     ————————————————————*/
  414.     
  415.     thisRect = (*window).portRect;
  416.     thisRect.left = thisRect.right - 14;
  417.     thisRect.top = thisRect.bottom - 14;    
  418.     thisRect.right += 2;
  419.     thisRect.bottom += 2;
  420.  
  421.     EraseRect( &thisRect );                    /* clear it out in case program doesn't */
  422.     
  423.     if ( (*(WindowPeek)window).hilited ) {    /* the size box chevrons */
  424.  
  425.         PlotSICN(&thisRect, &GrowSICN);
  426.  
  427. /*        thisRect.top += 4;
  428.         thisRect.left += 4;
  429.         thisRect.bottom -= 2;
  430.         thisRect.right -= 2;
  431.         PaintRect( &thisRect );
  432.         OffsetRect( &thisRect, -2, -2 );
  433.         thisRect.right -= 1;
  434.         thisRect.bottom -= 1;
  435.         EraseRect( &thisRect );
  436.         thisRect.right -= 1;
  437.         thisRect.bottom -= 1;
  438.         PaintRect( &thisRect );
  439.         thisRect.right -= 3;
  440.         thisRect.bottom -= 3;
  441.         EraseRect( &thisRect );
  442. */
  443.     }
  444.     
  445. } /* end of drawGrowIcon() */
  446.  
  447. /*————————————————————
  448.             set up the window
  449. ————————————————————*/
  450. setupWindow( variation, window, parameter )
  451.     short        variation;        /* variation code on this type window */
  452.     WindowPtr    window;            /* pointer to the window */
  453.     long        parameter;        /* parameter used for many things */
  454. {
  455.     SysEnvRec    thisWorld;
  456.     OSErr        error;
  457.     GDHandle    thisDevice;
  458.     Rect        thisRect;
  459.     GrafPtr     savedPort;   
  460.     GrafPort    tempPort; 
  461.     
  462.     (*(WindowPeek)window).dataHandle = NewHandle( (long)sizeof(WSDRecord) );
  463.     
  464.     if ( variation == (documentProc+8) || variation == (documentProc+12) || variation == (documentProc+13)) {
  465.         (*(WindowPeek)window).spareFlag = true;
  466.         if ( (*(WindowPeek)window).dataHandle != nil ) {
  467.             error = SysEnvirons( 1, &thisWorld );
  468.             /* if ( error == noErr && thisWorld.hasColorQD ) {
  469.                 thisDevice = GetMainDevice();
  470.                 thisRect = (**thisDevice).gdRect;
  471.                 thisRect.top += MBarHeight;
  472.             } else */ {
  473.                 GetPort(&savedPort);                /* finding screenBits w/o globals */
  474.                 OpenPort(&tempPort);
  475.                 thisRect = tempPort.portRect;
  476.                 SetPort(savedPort); 
  477.                 ClosePort(&tempPort);
  478.                 thisRect.top += MBarHeight;            /* make way for the menubar */
  479.             }
  480.             InsetRect( &thisRect, 4, 4 );            /* make way for edges */
  481.             thisRect.top += 16;                        /* make way for what's left of title */
  482.             (**(WSDHandle)(*(WindowPeek)window).dataHandle).stdState = thisRect;
  483.             (**(WSDHandle)(*(WindowPeek)window).dataHandle).userState = thisRect;
  484.         }
  485.     } else {
  486.         (*(WindowPeek)window).spareFlag = false;
  487.         /* (*(WindowPeek)window).dataHandle = nil; */
  488.     }
  489.     buttonState = false;
  490.     
  491. } /* end of setupWindow() */
  492.  
  493. /*————————————————————
  494.             kill the window
  495. ————————————————————*/
  496. killWindow( variation, window, parameter )
  497.     short        variation;        /* variation code on this type window */
  498.     WindowPtr    window;            /* pointer to the window */
  499.     long        parameter;        /* parameter used for many things */
  500. {
  501.     Rect        growingRect;
  502.     
  503.     /* if ( (*(WindowPeek)window).spareFlag ) { */
  504.         DisposHandle( (*(WindowPeek)window).dataHandle );
  505.         (*(WindowPeek)window).dataHandle = nil;
  506.     /* } */
  507.     
  508. } /* end of setupWindow() */